/* @flow */

import {
  no,
  noop,
  identity
} from 'shared/util'

import {LIFECYCLE_HOOKS} from 'shared/constants'

export
type
Config = {
  // user
  optionMergeStrategies: {[key: string
]:
Function
}
;
silent: boolean;
productionTip: boolean;
performance: boolean;
devtools: boolean;
errorHandler: ? (err: Error, vm: Component, info: string) => void;
warnHandler: ? (msg: string, vm: Component, trace: string) => void;
ignoredElements: Array < string | RegExp >;
keyCodes: {
  [key
:
  string
]:
  number | Array < number >
}
;

// platform
isReservedTag: (x
? : string
) =>
boolean;
isReservedAttr: (x
? : string
) =>
boolean;
parsePlatformTagName: (x: string) => string;
isUnknownElement: (x
? : string
) =>
boolean;
getTagNamespace: (x
? : string
) =>
string | void;
mustUseProp: (tag: string, type: ?string, name: string) => boolean;

// private
async: boolean;

// legacy
_lifecycleHooks: Array < string >;
}
;

export default ({
                  /**
                   * Option merge strategies (used in core/util/options)
                   */
                  // $flow-disable-line
                  optionMergeStrategies: Object.create
(null),

  /**
   * Whether to suppress warnings.
   */
  silent
:
false,

  /**
   * Show production mode tip message on boot?
   */
  productionTip
:
process.env.NODE_ENV !== 'production',

  /**
   * Whether to enable devtools
   */
  devtools
:
process.env.NODE_ENV !== 'production',

  /**
   * Whether to record perf
   */
  performance
:
false,

  /**
   * Error handler for watcher errors
   */
  errorHandler
:
null,

  /**
   * Warn handler for watcher warns
   */
  warnHandler
:
null,

  /**
   * Ignore certain custom elements
   */
  ignoredElements
:
[],

  /**
   * Custom user key aliases for v-on
   */
  // $flow-disable-line
  keyCodes
:
Object.create(null),

  /**
   * Check if a tag is reserved so that it cannot be registered as a
   * component. This is platform-dependent and may be overwritten.
   */
  isReservedTag
:
no,

  /**
   * Check if an attribute is reserved so that it cannot be used as a component
   * prop. This is platform-dependent and may be overwritten.
   */
  isReservedAttr
:
no,

  /**
   * Check if a tag is an unknown element.
   * Platform-dependent.
   */
  isUnknownElement
:
no,

  /**
   * Get the namespace of an element
   */
  getTagNamespace
:
noop,

  /**
   * Parse the real tag name for the specific platform.
   */
  parsePlatformTagName
:
identity,

  /**
   * Check if an attribute must be bound using property, e.g. value
   * Platform-dependent.
   */
  mustUseProp
:
no,

  /**
   * Perform updates asynchronously. Intended to be used by Vue Test Utils
   * This will significantly reduce performance if set to false.
   */
  async
:
true,

  /**
   * Exposed for legacy reasons
   */
  _lifecycleHooks
:
LIFECYCLE_HOOKS
}:
Config
)
